import { IAction } from "@scmt/common-components";
import { useSelectSpecimens } from "./specimen";
import { SpecimenEntity as RawSpecimenEntity } from "@scmt/api-lis-specimen";
import { usePrePrint } from "./prePrint";
import { ESpecimenStatus } from "@scmt/api-common";
import { useData } from "./data";
import { useUtils } from "@scmt/lib-utils";
import { useApi } from "@scmt/core-api";
import { useRequest } from "@scmt/common-hooks";

interface SpecimenEntity extends RawSpecimenEntity {
  __destoring?: boolean;
}

export const useOnPageActions = () => {
  const $api = useApi();

  const { request } = useRequest({
    destory: (id: string) => {
      return $api.lis.specimen.destroy(id);
    },
  });

  const onPageActions = (action: IAction, model?: SpecimenEntity) => {
    const $utils = useUtils();
    const { groupedData, getGroupKey, getData } = useData();
    const { selectSpecimens } = useSelectSpecimens();
    const { print } = usePrint();
    const { cancel } = useCancellation();
    const { collect } = useCollection();
    const { viewTrajectory } = useTrajectory();

    let specimen = model ? model : selectSpecimens.value;
    const shouldSynchronousState = ([] as SpecimenEntity[])
      .concat(specimen)
      .some((i) => i.state !== ESpecimenStatus.NOTGENERATED);

    //如果不是待生成的状态，都应该同步合管的数据
    if (shouldSynchronousState) {
      if ($utils.objects.isPlainObj(specimen)) {
        const specimenArr =
          groupedData.value[
            (specimen as SpecimenEntity)[
              getGroupKey(specimen as SpecimenEntity)
            ]
          ];

        if (specimenArr.length > 1) {
          specimen = specimenArr;
        }
      } else {
        const keys = new Set(
          (specimen as SpecimenEntity[]).map((i) => i[getGroupKey(i)])
        );
        specimen = Array.from(keys).reduce(
          (acc, key) => acc.concat(groupedData.value[key]),
          [] as SpecimenEntity[]
        );
      }
    }

    switch (action.event) {
      // 打印
      case "print":
        print(specimen);
        break;
      // case "merge-print":
      //   print(model ? model : selectSpecimens.value);
      //   break;
      // 作废
      case "cancel":
        cancel(specimen);
        break;
      // 采集
      case "collection":
      case "recollection":
      case "completeCollection":
        collect(specimen);
        break;
      // 标本轨迹
      case "check":
        viewTrajectory(
          $utils.objects.isPlainObj(specimen)
            ? (specimen as SpecimenEntity)
            : (specimen as SpecimenEntity[])[0]
        );
        break;
      case "destroy":
        if (model) {
          model.__destoring = true;
          request("destory", {
            params: model!.id,
            onSuccess: () => {
              getData({
                pageNum: 1,
              });
            },
          }).finally(() => {
            model!.__destoring = false;
          });
        }

        break;
    }
  };

  return {
    onPageActions,
  };
};

// 打印对象缓存
const _pritingSpecimens = ref<Array<SpecimenEntity>>([]);
const _pritingMergeSpecimens = ref<Array<SpecimenEntity[]>>([]);

export const usePrint = () => {
  const { prePrint, editingObj, onSaved } = usePrePrint();
  const printingSpecimens = computed(() => _pritingSpecimens.value);
  const printingMergeSpecimens = computed(() => _pritingMergeSpecimens.value);
  const printModelVisible = computed({
    get() {
      return (
        _pritingSpecimens.value.filter(Boolean).length > 0 ||
        _pritingMergeSpecimens.value.filter(Boolean).length > 0
      );
    },
    set(val) {
      if (!val) {
        _pritingSpecimens.value = [];
        _pritingMergeSpecimens.value = [];
      }
    },
  });
  const print = (specimens: SpecimenEntity | SpecimenEntity[]) => {
    // 待生成
    const preConfirm = ([] as SpecimenEntity[])
      .concat(specimens)
      .some((i) => i.state === ESpecimenStatus.NOTGENERATED);

    if (preConfirm) {
      prePrint(specimens, ({ specimens, mergeSpecimens }) => {
        _pritingSpecimens.value = specimens || [];
        _pritingMergeSpecimens.value = mergeSpecimens || [];
      });
    } else {
      _pritingSpecimens.value = ([] as SpecimenEntity[]).concat(specimens);
    }
  };

  return {
    prePrintEditingObj: editingObj,
    printModelVisible,
    printingSpecimens,
    printingMergeSpecimens,
    print,
    onPreSaved: onSaved,
  };
};

// 作废对象缓存
const _cancellationSpecimens = ref<Array<SpecimenEntity>>([]);

export const useCancellation = () => {
  const cancellationSpecimens = computed(() => _cancellationSpecimens.value);

  const cancellationModelVisible = computed({
    get() {
      return _cancellationSpecimens.value.filter(Boolean).length > 0;
    },
    set(val) {
      !val && (_cancellationSpecimens.value = []);
    },
  });

  const cancel = (specimens: SpecimenEntity | SpecimenEntity[]) => {
    _cancellationSpecimens.value = ([] as SpecimenEntity[]).concat(specimens);
  };

  return {
    cancel,
    cancellationModelVisible,
    cancellationSpecimens,
  };
};

// 打印对象缓存
const _collectSingleSpecimen = ref<SpecimenEntity[]>([]);
const _collectSpecimens = ref<Array<SpecimenEntity>>([]);

export const useCollection = () => {
  const collectingSpecimen = computed(() => _collectSingleSpecimen.value);
  const collectingSpecimens = computed(() => _collectSpecimens.value);

  const collectModelVisible = computed({
    get() {
      return _collectSingleSpecimen.value.filter(Boolean).length > 0;
    },
    set(val) {
      !val && (_collectSingleSpecimen.value = []);
    },
  });

  const batchCollectModelVisible = computed({
    get() {
      return _collectSpecimens.value.filter(Boolean).length > 0;
    },
    set(val) {
      !val && (_collectSpecimens.value = []);
    },
  });

  const collect = (specimen: SpecimenEntity | SpecimenEntity[]) => {
    const specimens = ([] as SpecimenEntity[]).concat(specimen);
    const single = new Set(specimens.map((i) => i.barcode)).size === 1;
    console.log(specimens, single);
    if (single) {
      _collectSingleSpecimen.value = specimens;
    } else {
      _collectSpecimens.value = specimens;
    }
  };

  return {
    collect,
    collectModelVisible,
    collectingSpecimen,
    batchCollectModelVisible,
    collectingSpecimens,
  };
};

const _trajectorySpecimen = ref<null | SpecimenEntity>(null);
export const useTrajectory = () => {
  const trajectorySpecimen = computed(() => _trajectorySpecimen.value);

  const trajectoryModelVisible = computed({
    get() {
      return Boolean(_trajectorySpecimen.value);
    },
    set(val) {
      !val && (_trajectorySpecimen.value = null);
    },
  });

  const viewTrajectory = (specimen: SpecimenEntity) => {
    _trajectorySpecimen.value = specimen;
  };

  return {
    trajectoryModelVisible,
    trajectorySpecimen,
    viewTrajectory,
  };
};
